#pragma once
#include <sys/time.h>
#include <sys/epoll.h>
#include <pthread.h>
#include <netinet/in.h>

#include <map>
#include <string>
#include <deque>

#include "Thread.h"
#include "ThreadPool.h"
#include "Socket.h"
#include "Connect.h"

namespace sevent{

class Server;
class Loop
{
public:
	Loop(const std::string ip, const int port, std::string name);
	~Loop();

	int init();
	int start();
	int stop();
	int wait();

	bool started() const {
		return _started;
	}

	int lock();
	int unLock();

	void setName(std::string name){_name = name;}
	
	Server *getServer(){return _server;}
	void setServer(Server *server){_server = server;}
private:
	Server *_server;

	std::string _name;
	
	bool _started;

	pthread_mutex_t _mutex;
	pthread_cond_t _cond;

	Thread _thread; //for epoll
	int threadInit();
	int threadRun();
	int threadStop();

	Address _listenAddr;
	int _listenSock;
	
	int _epfd;
	struct epoll_event _epevents[1024];
	struct epoll_event _eplistenevent;
	
	std::map<int, Connect *> _connectMap; //the fd has been used
	
	int checkTask();
	
	int closeConnect(int fd);
	int prepareConnect(Connect *c);
	Connect* getConnect(int fd);
	
	Loop(const Server &other);
	Loop &operator=(const Server &other);
};


}
